package isssr.control.src;

import isssr.boundary.src.OrganizationalGoalCRUDBoundary;
import isssr.dao.exception.DAOException;
import isssr.dao.factory.DAOFactory;
import isssr.dao.factory.DAOFactoryType;
import isssr.dao.interfaces.RecordPagination;
import isssr.dao.interfaces.RecordSorting;
import isssr.dao.interfaces.UserDAO;
import isssr.entity.src.User;
import isssr.entity.src.UserContext;
import isssr.entity.src.UserDTO;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.ViewScoped;

import org.primefaces.model.SortOrder;

@ManagedBean(name="#{superOwnerSelectionControl}")
@ViewScoped

public class SuperOwnerSelectionControl implements Serializable {

	private static final long serialVersionUID = -8603915588658595688L;
	
	/*
	@ManagedProperty(value="#{organizationalGoalCRUDBoundary}")
	private OrganizationalGoalCRUDBoundary parentBoundary;
	*/
	@ManagedProperty(value="#{userContext}")
	private UserContext currentContext;
	
	
	public SuperOwnerSelectionControl() {
		System.out.println("super owner selection control created");
	}

	/*
	public void setParentBoundary(OrganizationalGoalCRUDBoundary parentBoundary) {
		System.out.println("set parent boundary  ");

		this.parentBoundary = parentBoundary;
	}*/
	
	
	public void setCurrentContext(UserContext currentContext) {
		this.currentContext = currentContext;
	}

	/*
	public List<UserDTO> loadCurrentSelection() {
		List<UserDTO> currentSelection 	= new ArrayList<UserDTO>();
		List<User> superOwnerList 		= null;   
		
		if(this.parentBoundary != null)
		{
			 superOwnerList = this.parentBoundary.getSuperOwnerList();
			 for(User superOwner : superOwnerList)
			 {
				 UserDTO data = superOwner.getDTO();
				 currentSelection.add(data);
			 }
		}
			
		return currentSelection;
	}*/
	
	/*
	public void saveCurrentSelection(List<UserDTO> selectionList) {
		if(this.parentBoundary != null)
		{
			List<User> superOwnerList = new ArrayList<User>();
			for(UserDTO selected : selectionList)
			{
				User selectedOwner = null;
				try {
					selectedOwner = this.getUserFromDto(selected);
				} catch (DAOException e) {
					e.printStackTrace();
				}
				superOwnerList.add(selectedOwner);
			}
			this.parentBoundary.setSuperOwnerList(superOwnerList);
		}	
	}*/
	
	
	@SuppressWarnings("finally")
	public int loadElegibleSuperOwner(int firstRecord, int pageSize, String sortField, SortOrder sortOrder,
			Map<String, String> filters, List<UserDTO> resultList) {
		
		// set pagination
		RecordPagination pagination = new RecordPagination();
		pagination.firstResult 		= firstRecord;
		pagination.pageSize			= pageSize;
		
		// set sort order
		RecordSorting sorting = this.setRecordSorting(sortField, sortOrder);
		
		// convert filters
		Map<String, Object> filtersMap = this.castStringMapToObjectMap(filters);
		
		// retrieve UserDAO
		DAOFactory factory = DAOFactory.getDAOFactory(DAOFactoryType.HIBERNATE);
		UserDAO userDao = factory.getUserDAO();
		
		
		// retrieve current user
		User currentUser = this.currentContext.getUser();
		
		// create result list
		int resultNumber = 0;
		List<User> tempList = new ArrayList<User>();
		
		
		try {
			resultNumber =  userDao.getEligibleSuper(tempList, currentUser, filtersMap, sorting, pagination);
			for(int i=0; i<tempList.size(); i++)
			{
				User retrievedUser = tempList.get(i);
				UserDTO userData = retrievedUser.getDTO();
				resultList.add(userData);
			}
			
		} catch (DAOException e) {
			e.printStackTrace();
		}
	
		finally {
			return resultNumber;	
		}
		
	}
	
	
	private RecordSorting setRecordSorting(String sortField, SortOrder sortOrder) {
		
		RecordSorting.SortOrder ordering;
	
		switch (sortOrder) {
		case ASCENDING:
			ordering = RecordSorting.SortOrder.ASCENDING;
			break;
		case DESCENDING:
			ordering = RecordSorting.SortOrder.DESCENDING;
			break;
		default:
			ordering = RecordSorting.SortOrder.UNSORTED;
			break;
		}
		
		return new RecordSorting(sortField, ordering);
	}
	
	
	private Map<String, Object> castStringMapToObjectMap(Map<String, String> stringMap) {
		
		Map<String, Object> objectMap = new HashMap<>();
		
		for(Map.Entry<String, String> entry : stringMap.entrySet())
		{
			String key 		= entry.getKey();
			Object value 	= (Object) entry.getValue(); 
			objectMap.put(key, value);
		}
		
		return objectMap;
	}
	
	
	private User getUserFromDto(UserDTO data) throws DAOException {
		DAOFactory factory 	= DAOFactory.getDAOFactory(DAOFactoryType.HIBERNATE);
		UserDAO userDao	 	= factory.getUserDAO();
		String username	 	= data.getUsername();
		User retrievedUser 	= userDao.getByUsername(username);
		return retrievedUser;
	}
	
}
